package com.yqg.education.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yqg.education.controller.dto.ExamAnswerDetailDTO;
import com.yqg.education.entity.*;
import com.yqg.education.mapper.*;
import com.yqg.education.service.IExamAnswerDetailService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yqg.education.service.IExamLogService;
import com.yqg.education.service.IExampaperService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.sql.Wrapper;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * ExamAnswerDetailServiceImpl 服务实现类
 *
 * @author 张芸博
 * @since 2025-04-10
 */
@Service
public class ExamAnswerDetailServiceImpl extends ServiceImpl<ExamAnswerDetailMapper, ExamAnswerDetail> implements IExamAnswerDetailService {
    @Resource
    private ExamSignMapper examSignMapper;

    @Resource
    private ExamLogMapper examLogMapper;
    @Resource
    private QuestionMapper questionMapper;

    @Resource
    private ExamquestionMapper examquestionMapper;
    @Resource
    private IExamLogService examLogService;
    @Resource
    private IExampaperService exampaperService;
    @Resource
    private ExamHistoryLogMapper examHistoryLogMapper;
    @Resource
    private StuHonorMapper stuHonorMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void stuSubmitExampaper(ExamAnswerDetailDTO examAnswerDetailDTO) {
        // 根据学员ID和课程ID查询试卷ID
        Long exampaperId = examSignMapper.getExampaperIdByStuIdAndCourseId(examAnswerDetailDTO.getStuId(), examAnswerDetailDTO.getCourseId());
        // 从DTO中提取题目ID列表
        List<Long> questionIds = examAnswerDetailDTO.getAnswerList().stream()
                .map(answerMap -> Long.valueOf((Integer) answerMap.get("id")))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        // 获取题目信息
        Map<Long, Question> questionMap = questionMapper.stuSelectList(questionIds).stream()
                .collect(Collectors.toMap(Question::getId, Function.identity()));

        // 该学员的分数
        final BigDecimal[] exampaperGetScore = {new BigDecimal(0)};

        // 查询学员回答题目的主键ID
        LambdaQueryWrapper<ExamAnswerDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ExamAnswerDetail::getExampaperId, exampaperId)
                .eq(ExamAnswerDetail::getStuId, examAnswerDetailDTO.getStuId())
                .in(ExamAnswerDetail::getQuestionId, questionIds) // 直接关联题库ID
                .eq(ExamAnswerDetail::getIsDelete, 0); // 只查询未删除的记录

        List<ExamAnswerDetail> examAnswerDetailList = this.list(queryWrapper);
        // 构建题目ID到主键ID的映射
        Map<Long, Long> questionIdToRecordIdMap = new HashMap<>();
        if (examAnswerDetailList != null && !examAnswerDetailList.isEmpty()) {
            examAnswerDetailList.forEach(examAnswerDetail -> {
                questionIdToRecordIdMap.put(examAnswerDetail.getQuestionId(), examAnswerDetail.getId());
            });
        }

        // 将学员答案存入数据库
        List<ExamAnswerDetail> answerDetails = examAnswerDetailDTO.getAnswerList().stream()
                .map(answerMap -> {
                    Long questionId = Long.valueOf((Integer) answerMap.get("id"));
                    String studentAnswer = (String) answerMap.get("answer");

                    ExamAnswerDetail detail = new ExamAnswerDetail();
                    // 这里判断是不是重新考试
                    if (examAnswerDetailList != null && !examAnswerDetailList.isEmpty()) {
                        detail.setId(questionIdToRecordIdMap.get(questionId));
                    }
                    detail.setExampaperId(exampaperId);
                    detail.setStuId(examAnswerDetailDTO.getStuId());
                    detail.setQuestionId(questionId);

                    ObjectMapper mapper = null;
                    // 将学员答案转换为JSON格式
                    try {
                        // 尝试将学员答案解析为JSON
                        mapper = new ObjectMapper();
                        Object answerObj = mapper.readTree(studentAnswer);
                        // 再将对象转换回格式化的JSON字符串
                        detail.setAnswer(mapper.writeValueAsString(answerObj));
                    } catch (Exception e) {
                        // 如果解析失败，说明不是有效的JSON，将其包装为JSON字符串
                        try {
                            detail.setAnswer(mapper.writeValueAsString(studentAnswer));
                        } catch (JsonProcessingException ex) {
                            // 这种情况很少发生，使用原始答案
                            detail.setAnswer(studentAnswer);
                            ex.printStackTrace();
                        }
                    }
                    // 判断是否正确
                    Question question = questionMap.get(questionId);
                    String questionType = question.getQuestionType();

                    try {
                        // 根据题目类型选择不同的验证逻辑
                        switch (questionType) {
                            case "1": // 单选题 - 答案格式："A"
                            case "3": // 判断题 - 答案格式："F"
                                String correctAnswer = question.getAnswer();
                                if (correctAnswer.startsWith("\"") && correctAnswer.endsWith("\"") && correctAnswer.length() >= 2) {
                                    correctAnswer = correctAnswer.substring(1, correctAnswer.length() - 1);
                                }
                                if (studentAnswer.equals(correctAnswer)) {
                                    detail.setIsTrue(0);
                                    BigDecimal score = examquestionMapper.getScoreByQuestionId(questionId,exampaperId);
                                    exampaperGetScore[0] = exampaperGetScore[0].add(score);
                                } else {
                                    detail.setIsTrue(1);
                                }
                                break;

                            case "2": // 多选题 - 答案格式：["A","C"]
                                try {
                                    // 解析学员答案和正确答案为字符串数组
                                    String[] studentArray = mapper.readValue(studentAnswer, String[].class);
                                    String[] correctArray = mapper.readValue(question.getAnswer(), String[].class);

                                    // 对数组进行排序后比较（忽略元素顺序）
                                    Arrays.sort(studentArray);
                                    Arrays.sort(correctArray);

                                    boolean isCorrect = Arrays.equals(studentArray, correctArray);

                                    if (isCorrect) {
                                        detail.setIsTrue(0);
                                        BigDecimal score = examquestionMapper.getScoreByQuestionId(questionId,exampaperId);
                                        exampaperGetScore[0] = exampaperGetScore[0].add(score);
                                    } else {
                                        detail.setIsTrue(1);
                                    }
                                } catch (Exception e) {
                                    System.err.println("解析多选题答案出错: " + e.getMessage());
                                    detail.setIsTrue(1);
                                }
                                break;


                            case "4": // 填空题 - 答案格式：["爱迪生","美"]
                                // 解析正确答案（数据库中存储的JSON数组）
                                String[] correctArray = mapper.readValue(question.getAnswer(), String[].class);

                                // 处理学员答案
                                String[] studentArray;

                                // 检查学员答案是否已经是JSON格式
                                if (studentAnswer.startsWith("[") && studentAnswer.endsWith("]")) {
                                    // 已经是JSON数组格式
                                    studentArray = mapper.readValue(studentAnswer, String[].class);
                                } else if (studentAnswer.contains(",")) {
                                    // 逗号分隔的字符串，转换为数组
                                    studentArray = studentAnswer.split(",");
                                    // 去除每个元素的首尾空格
                                    for (int i = 0; i < studentArray.length; i++) {
                                        studentArray[i] = studentArray[i].trim();
                                    }
                                } else {
                                    // 单个答案，转换为单元素数组
                                    studentArray = new String[]{studentAnswer};
                                }

                                // 比较两个数组（忽略顺序）
                                boolean isCorrect = Arrays.equals(
                                        Arrays.stream(studentArray).sorted().toArray(),
                                        Arrays.stream(correctArray).sorted().toArray()
                                );

                                if (isCorrect) {
                                    detail.setIsTrue(0);
                                    BigDecimal score = examquestionMapper.getScoreByQuestionId(questionId,exampaperId);
                                    exampaperGetScore[0] = exampaperGetScore[0].add(score);
                                } else {
                                    detail.setIsTrue(1);
                                }
                                break;
                            default:
                                // 未知类型，默认为错误
                                detail.setIsTrue(1);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        detail.setIsTrue(1); // 发生错误时默认为错误
                    }
                    return detail;
                })
                .collect(Collectors.toList());
        this.saveOrUpdateBatch(answerDetails);

        // 处理考试记录数据
        LocalDateTime startTime = examAnswerDetailDTO.getStartTime();
        LocalDateTime endTime = examAnswerDetailDTO.getEndTime();
        // 计算时间差
        Duration duration = Duration.between(startTime, endTime);

        // 将差值转换为LocalTime格式
        long seconds = duration.getSeconds();
        long absSeconds = Math.abs(seconds);
        LocalTime timeDifference = LocalTime.of(
                (int) (absSeconds / 3600),
                (int) ((absSeconds % 3600) / 60),
                (int) (absSeconds % 60)
        );
        Integer isPass = 0;
        // 获取及格分数线
        Exampaper exampaper = exampaperService.getById(exampaperId);
        BigDecimal exampaperPassScore = exampaper.getExampaperPassScore();
        if(exampaperGetScore[0].compareTo(exampaperPassScore) < 0){
            // 低于规定分数不及格
            isPass = 0;
        }else {
            // 高于或等于规定分数及格
            isPass = 1;
        }
        ExamLog examLog = examLogMapper.stuFindExamLogByStuIdAndCourseId(examAnswerDetailDTO.getStuId(), examAnswerDetailDTO.getCourseId());
        examLog.setStartTime(startTime);
        examLog.setEndTime(endTime);
        examLog.setFlow(1);
        examLog.setAnswerTime(timeDifference);
        examLog.setExampaperGetScore(exampaperGetScore[0]);
        examLog.setIsPass(isPass);
        examLogService.saveOrUpdate(examLog);

        LambdaQueryWrapper<ExamHistoryLog> examHistoryLogQueryWrapper = new LambdaQueryWrapper<>();
        examHistoryLogQueryWrapper.eq(ExamHistoryLog::getIsDelete, 0);
        examHistoryLogQueryWrapper.eq(ExamHistoryLog::getExamLogId, examLog.getId());
        Long count = examHistoryLogMapper.selectCount(examHistoryLogQueryWrapper);
        ExamHistoryLog examHistoryLog = new ExamHistoryLog();
        examHistoryLog.setExamLogId(examLog.getId());
        examHistoryLog.setScore(exampaperGetScore[0]);
        examHistoryLog.setCount(count + 1);
        examHistoryLog.setCreateTime(LocalDateTime.now());
        examHistoryLogMapper.insert(examHistoryLog);

        if (isPass == 1) {
            StuHonor stuHonor = new StuHonor();
            stuHonor.setStuId(examLog.getStuId());
            stuHonor.setCourseId(examLog.getCourseId());
            stuHonor.setCreateTime(LocalDateTime.now());
            stuHonorMapper.insert(stuHonor);
        }

    }
}
